<template>
  <div :id="id" :style="{width:chartWidth,height: chartHeight}"></div>
</template>
<script>
/* 由于全局引入会将所有的echarts图表打包，导致体积过大，所以在本项目中，采用组建的形式按需引入 */
import * as echarts from 'echarts/core'
// 饼状图, 柱状图, 折线图, 仪表盘, 雷达图, 自定义, 旭日图
import { PieChart, BarChart, LineChart, GaugeChart, RadarChart, CustomChart, SunburstChart } from 'echarts/charts'
// 直角坐标系
import { GridComponent, TooltipComponent, TitleComponent, LegendComponent, DataZoomComponent } from 'echarts/components'

echarts.use([PieChart, BarChart, LineChart, GaugeChart, RadarChart, CustomChart, SunburstChart, GridComponent, TooltipComponent, TitleComponent, LegendComponent, DataZoomComponent])

export default {
  name: 'DrawBar',
  props: {
    id: {
      type: String,
      default: 'chart'
    },
    chartWidth: {
      type: String,
      default: '100%'
    },
    chartHeight: {
      type: String,
      default: '100%'
    }
  },
  data() {
    return {
      chart: null,
      // 颜色列表
      colorList: ['#5470C6', '#91CC75', '#EE6666'],
      // 图表上下左右间距（上右下左）
      position: [100, 100, 100, 100],
      // 文字颜色
      txtColor: '#000',
      // 文字大小
      fontSize: 14,
      // y轴偏移量
      yAxisOffset: 24
    }
  },
  mounted() {
    this.chart = echarts.init(document.getElementById(this.id))
  },
  methods: {
    drawBarChart(options, otherMergeOptions = {}, megere = true) {
      console.log(this.deepClone(this.getOptions(options), otherMergeOptions))
      this.chart.setOption(this.deepClone(this.getOptions(options), otherMergeOptions), megere)
    },
    clear() {
      this.chart.clear()
    },
    // 深拷贝（obj里面的字段赋值到objClone）
    deepClone(objClone, obj) {
      if (obj && typeof obj === 'object') {
        for (const key in obj) {
          if (obj[key] && typeof obj[key] === 'object') {
            objClone[key] = typeof objClone[key] === 'object' ? Object.assign(objClone[key], this.deepClone(obj[key])) : this.deepClone(obj[key])
          } else {
            objClone[key] = obj[key]
          }
        }
      }
      return objClone
    },
    // 获取charts参数
    getOptions({ xAxisName, yAxisArr, title, data } = {}) {
      // 拼接yAxis数据（可能会有多个y轴）
      const { yKeyToAxisIdxObj, yAxis, legendData } = this.getYAxisOption(yAxisArr)
      // 获取横纵坐标数据
      const { xAxisData, series } = this.getDataOption(data, xAxisName, yAxisArr, yKeyToAxisIdxObj)

      return Object.assign(this.getBaseOption(title, xAxisData, legendData), { series, yAxis })
    },
    // 获取横纵坐标数据
    getDataOption(data, xAxisName, yAxisArr, yKeyToAxisIdxObj) {
      // 整理x轴和y轴数据
      const xAxisData = []
      const seriesObj = {}
      data.forEach(dataItem => {
        // 推入x轴数据
        xAxisData.push(dataItem[xAxisName])
        // 推入y轴数据
        yAxisArr.forEach(yAxisItem => {
          // 当前项值
          const val = dataItem[yAxisItem.key]
          // 判断obj中是否已经存在这个key
          if (!seriesObj[yAxisItem.key]) {
            // 不存在则赋值
            seriesObj[yAxisItem.key] = {
              data: [val],
              yAxisIndex: yKeyToAxisIdxObj[yAxisItem.key],
              type: yAxisItem.type,
              name: yAxisItem.name,
              stack: yAxisItem.stack
            }
          } else {
            seriesObj[yAxisItem.key].data.push(val)
          }
        })
      })
      return {
        xAxisData,
        series: Object.values(seriesObj)
      }
    },
    // 拼接yAxis数据（可能会有多个y轴）
    getYAxisOption(yAxisArr) {
      // 当前y轴存在哪些类型
      const yAxisObj = {}
      // key对应yAxis中索引值
      const yKeyToAxisIdxObj = {}
      const legendData = []
      // 拼接yAxis数据
      const yAxis = yAxisArr.reduce((arr, item, idx) => {
        legendData.push(item.name)
        // 如果是非独立的y轴，并且之前有同类型存在  直接返回
        if (!item.independent && typeof yAxisObj[item.type] === 'number') {
          // 赋值之前已存在类型的索引值
          yKeyToAxisIdxObj[item.key] = yAxisObj[item.type]
          return arr
        }
        // 当前图表类型轴设置为true
        yAxisObj[item.type] = arr.length
        // 当前图表轴数据（y轴）
        const obj = {
          type: 'value',
          // name: item.name,
          // min(value) {
          //   return Math.floor(value.min - 60 > 0 ? value.min - 60 : value.min)
          // },
          splitLine: {
            show: true
          },
          axisLabel: {
            color: this.colorList[idx],
            fontSize: this.fontSize,
            lineHeight: this.fontSize * 2,
            formatter: item.formatter
          },
          axisTick: {
            inside: true
          },
          axisLine: {
            show: true,
            lineStyle: {
              color: this.colorList[idx]
            },
            symbol: ['none', 'arrow'],
            symbolSize: [5, 10],
            symbolOffset: [10, 10]
          }
        }
        if (arr.length > 0) obj.position = 'right'
        if (arr.length > 1) {
          obj.offset = (arr.length - 1) * this.yAxisOffset
        }
        // 合并Y轴配置
        if (item.options) {
          arr.push(this.deepClone(obj, item.options))
        } else {
          arr.push(obj)
        }
        // 当前key对应轴的索引
        yKeyToAxisIdxObj[item.key] = arr.length - 1
        return arr
      }, [])
      return {
        // y轴key对应yAxis索引位置
        yKeyToAxisIdxObj,
        // 图例数组
        legendData,
        // yAxis参数
        yAxis
      }
    },
    // 获取基础参数
    getBaseOption(title, xAxisData, legendData) {
      // 图例字段
      const legend = {
        show: true,
        top: 0,
        left: 10,
        textStyle: {
          color: this.txtColor,
          fontSize: this.fontSize
        },
        itemGap: 20,
        inactiveColor: '#000'
      }
      if (legendData) legend.data = legendData
      return {
        // 颜色列表
        color: this.colorList,
        title: {
          text: title,
          left: 'center',
          textStyle: {
            fontSize: this.fontSize,
            lineHeight: this.fontSize,
            color: this.txtColor
          }
        },
        tooltip: {
          trigger: 'axis',
          // 使用回调函数
          // formatter: function (val) {
          //   console.log(val)
          //   return `<span>${val[0].name}</span><br/>` + val.map(v => `<div style="margin:0;line-height:1;padding:0">${v.marker}${v.seriesName}<span style="margin-left:10px">${v.value}</span></div>`).join('<br/>')
          // },
          axisPointer: {
            type: 'cross',
            label: {
              backgroundColor: '#000'
            },
            crossStyle: {
              color: '#999'
            }
          }
        },
        grid: {
          top: this.position[0],
          right: this.position[1],
          bottom: this.position[2],
          left: this.position[3],
          containLabel: false
        },
        legend,
        xAxis: {
          type: 'category',
          data: xAxisData,
          axisLabel: {
            show: true,
            textStyle: {
              color: this.txtColor,
              fontSize: this.fontSize,
              lineHeight: 30
            }
            // showMaxLabel: false
          },
          axisTick: {
            inside: true,
            alignWithLabel: true
          },
          axisLine: {
            lineStyle: {
              color: this.txtColor
            },
            symbol: ['none', 'arrow'],
            symbolSize: [5, 10]
          }
        }
      }
    }
  }
}
</script>
